import { useMemo, useState, forwardRef, useImperativeHandle, useCallback } from 'react';
import { Form, Button, Popover, Space, Tooltip } from 'antd';
import {
  ProForm,
  ProFormDependency,
  ProFormList,
  ProFormSelect,
  ProFormText,
} from '@ant-design/pro-components';
import { cloneDeep, debounce } from 'lodash';
import type { ProColumns } from '@ant-design/pro-components';

import {
  include,
  equalTo,
  greaterOrEqual,
  lessThanOrequal,
  isNull,
  notNull,
  notInclude,
} from '@/utils/filter';
import type { FormInstance } from 'antd/es/form/Form';
import { FilterOutlined } from '@ant-design/icons';
import { useHistory } from '@/hooks/useHistory';

interface FilterProps {
  columns: ProColumns<any>[];
  syncUrl: boolean;
  record: any[];
  setDataSource?: (dataSource: any[]) => void;
  onFilterChange?: (filter: any) => void;
  showFilterButton?: boolean;
  initalFilter?: any[];
  filterSyncUrl?: boolean;
}

interface FilterItem {
  field?: string;
  symbol?: string;
  value?: string;
}

export interface FilterHandler {
  form: FormInstance | null;
  getFilterValue: () => any[];
  handleFilterList: (filterList?: FilterItem[]) => void;
}

export const SYMBOL_TYPE = {
  include: 'include',
  notInclude: 'notInclude',
  moreOrEqual: 'me',
  lessOrEqual: 'le',
  equal: 'equal',
  isNull: 'isNull',
  notNull: 'notNull',
};

const Filter = forwardRef<FilterHandler, FilterProps>((props, ref) => {
  const {
    columns,
    record,
    setDataSource,
    syncUrl,
    onFilterChange,
    showFilterButton = false,
    initalFilter = [],
    filterSyncUrl = true,
  } = props;
  const [isFirstVisible, setFirstVisible] = useState<boolean>(false);
  const [form] = Form.useForm();
  const [filterCount, setFilterCount] = useState<number>(initalFilter?.length || 0);
  const { navigate, location } = useHistory();

  const fieldOptions = useMemo(() => {
    return columns
      .filter((item: any) => !item.hideOnCustomFilter)
      .map((item) => ({
        label: item.title as string,
        value: item.dataIndex as string,
      }));
  }, [columns]);


  const symbolOptions: { label: string; value: string }[] = useMemo(() => {
    return [
      {
        label: '包含',
        value: SYMBOL_TYPE.include,
      },
      {
        label: '不包含',
        value: SYMBOL_TYPE.notInclude,
      },
      {
        label: '大于等于',
        value: SYMBOL_TYPE.moreOrEqual,
      },
      {
        label: '小于等于',
        value: SYMBOL_TYPE.lessOrEqual,
      },
      {
        label: '等于',
        value: SYMBOL_TYPE.equal,
      },
      {
        label: '为空',
        value: SYMBOL_TYPE.isNull,
      },
      {
        label: '不为空',
        value: SYMBOL_TYPE.notNull,
      },
    ];
  }, []);

  const handleSyncUrl = (filterArr: any[]) => {
    const newQuery = cloneDeep(location.query || {});
    if (syncUrl) {
      const strFilterArr = JSON.stringify(filterArr.length === 0 ? '' : filterArr);
      newQuery.filter = encodeURIComponent(strFilterArr);
    } else {
      delete newQuery.filter;
    }
    if (filterSyncUrl) {
      navigate({
        pathname: location.pathname,
        search: { ...newQuery },
      });
    }
  };

  const createFilterFunc = (symbol: string) => {
    switch (symbol) {
      case SYMBOL_TYPE.equal:
        return equalTo;
      case SYMBOL_TYPE.lessOrEqual:
        return lessThanOrequal;
      case SYMBOL_TYPE.moreOrEqual:
        return greaterOrEqual;
      case SYMBOL_TYPE.include:
        return include;
      case SYMBOL_TYPE.notInclude:
        return notInclude;
      case SYMBOL_TYPE.isNull:
        return isNull;
      case SYMBOL_TYPE.notNull:
        return notNull;
      default:
        return function () {
          return [];
        };
    }
  };

  const handleFilter = useCallback(
    (filterList: { field: string; symbol: string; value?: string }[]) => {
      if (!setDataSource) return;

      const arr = filterList.reduce((pre, cur) => {
        const { field, symbol, value } = cur;
        const func = createFilterFunc(symbol);
        return func(pre, field, value as string);
      }, record);
      setDataSource(arr);
    },
    [record, setDataSource],
  );

  const getFilterValue = useCallback(
    (filterList = (form.getFieldValue('filter_list') as FilterItem[]) || initalFilter) => {
      return filterList
        .map((item: any) => {
          if (item.field && item.symbol) {
            if (item.symbol === SYMBOL_TYPE.isNull || item.symbol === SYMBOL_TYPE.notNull) {
              // console.log('有效筛选条件', item);
              return item;
            } else if (item.value) {
              // console.log('有效筛选条件', item);
              return item;
            } else {
              // console.log('无效筛选条件', item);
              return false;
            }
          } else {
            // console.log('无效筛选条件', item);
            return false;
          }
        })
        .filter(Boolean);
    },
    [],
  );

  const handleFilterList = useCallback(
    (filterList = (form.getFieldValue('filter_list') as FilterItem[]) || initalFilter) => {
      const validList = getFilterValue(filterList);
      setFilterCount(validList.length);
      handleSyncUrl(validList);
      if (onFilterChange) {
        onFilterChange(validList);
        setDataSource?.(record);
      } else {
        handleFilter(validList as { field: string; symbol: string; value?: string }[]);
      }
      return validList;
    },
    [form, handleFilter],
  );

  const debounceHandleFilterList = debounce(() => {
    if (showFilterButton) return;
    handleFilterList();
  }, 1000);

  const content = (
    <ProForm
      className="filter_form"
      form={form}
      submitter={false}
      style={{
        width: 666,
        marginTop: 6,
      }}
      initialValues={{
        filter_list: initalFilter,
      }}
    >
      <ProFormList
        name="filter_list"
        copyIconProps={false}
        deleteIconProps={undefined}
        creatorButtonProps={{
          creatorButtonText: <span style={{ fontSize: 12 }}>添加筛选条件</span>,
        }}
        onAfterRemove={() => {
          if (showFilterButton) return;
          handleFilterList();
        }}
      >
        {({ key }) => {
          return (
            <Space key={key} size={6}>
              <ProFormSelect
                showSearch
                style={{ width: 210 }}
                name="field"
                placeholder={'请选择字段'}
                options={fieldOptions}
                fieldProps={{
                  onChange: () => {
                    if (showFilterButton) return;
                    handleFilterList();
                  },
                }}
              />
              <ProFormSelect
                style={{ width: 210 }}
                name="symbol"
                showSearch
                placeholder={'请选择符号'}
                options={symbolOptions}
                fieldProps={{
                  onChange: () => {
                    if (showFilterButton) return;
                    handleFilterList();
                  },
                }}
              />
              <ProFormDependency name={['symbol']}>
                {({ symbol }) => {
                  const isDisabled =
                    symbol === SYMBOL_TYPE.isNull || symbol === SYMBOL_TYPE.notNull;
                  return (
                    <ProFormText
                      name="value"
                      style={{ width: 210 }}
                      disabled={isDisabled}
                      placeholder={isDisabled ? '请输入' : ''}
                      fieldProps={{
                        onChange: debounceHandleFilterList,
                      }}
                    />
                  );
                }}
              </ProFormDependency>
            </Space>
          );
        }}
      </ProFormList>
      {showFilterButton && (
        <Form.Item
          style={{
            textAlign: 'right',
            marginBottom: 6,
          }}
        >
          <Button
            style={{ marginRight: 12 }}
            onClick={() => {
              form.setFieldValue('filter_list', []);
              handleFilterList();
              setFirstVisible(false);
            }}
          >
            重置
          </Button>
          <Button
            type="primary"
            icon={<FilterOutlined />}
            onClick={() => {
              handleFilterList();
              setFirstVisible(false);
            }}
          >
            筛选
          </Button>
        </Form.Item>
      )}
    </ProForm>
  );

  useImperativeHandle(ref, () => ({
    form: form,
    getFilterValue,
    handleFilterList,
  }));

  return (
    <Popover
      className="filter_popover"
      placement="bottomRight"
      trigger="click"
      title={
        <div
          className="font-weight-bold color-primary"
          style={{
            padding: '6px 0',
          }}
        >
          设置筛选条件
        </div>
      }
      content={content}
      open={isFirstVisible}
      onOpenChange={() => {
        setFirstVisible(!isFirstVisible);
      }}
    >
      {/* <Button type="primary" icon={<FilterOutlined />} className="relative">
        {t('__advanced_filter') || '高级过滤'}
        {filterCount > 0 && <div className="bubble large">{filterCount}</div>}
      </Button> */}
      <Tooltip title={'高级过滤'} key="$Filter">
        <Button type="link" className="table-element-toolbar-button">
          <FilterOutlined style={{ width: 24 }} />
          {filterCount > 0 && <div className="bubble small">{filterCount}</div>}
        </Button>
      </Tooltip>
    </Popover>
  );
});

export default Filter;
